package sfs

import (
	"embed"
	"io"
	pathpkg "path"
)

// NewServerFileSystemFromEmbedFS 根据嵌入的文件系统（embed.FS）和指定的路径创建一个新的服务器文件系统。
// 参数 embedfs 是嵌入的文件系统实例，path 是嵌入文件系统中的根路径，pathAlias 是该路径的别名。
// 如果加载嵌入文件系统失败，则返回错误。
// 返回创建的服务器文件系统实例或错误。
func NewServerFileSystemFromEmbedFS(embedfs embed.FS, path, pathAlias string) (*ServerFileSystem, error) {
	fs := FileSystem{}
	if e := loadEmbedFS(fs, embedfs, path, pathAlias); e != nil {
		return nil, e
	}
	return &ServerFileSystem{FileSystem: fs}, nil
}

func loadEmbedFS(fs FileSystem, embedfs embed.FS, path, pathAlias string) error {
	if f, e := embedfs.Open(path); e != nil {
		return e
	} else if s, e := f.Stat(); e != nil {
		return e
	} else if s.IsDir() {
		fs[pathAlias] = &DirInfo{
			name:    s.Name(),
			modTime: s.ModTime(),
		}
		if entries, e := embedfs.ReadDir(path); e != nil {
			return e
		} else {
			for _, entry := range entries { // 递归读取目录
				if e := loadEmbedFS(fs, embedfs, pathpkg.Join(path, "/", entry.Name()), pathpkg.Join(pathAlias, "/", entry.Name())); e != nil {
					return e
				}
			}
		}
	} else if b, e := io.ReadAll(f); e != nil {
		return e
	} else {
		fs[pathAlias] = &FileInfo{
			name:    s.Name(),
			modTime: s.ModTime(),
			content: b,
		}
	}
	return nil
}
